/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tencent.tendon.convert.json;

import com.tencent.tendon.convert.util.*;

/**
 *
 * @author nbzhang
 */
public abstract class JsonWriter {

    protected AnyArray stack;

    protected int count;

    //-----------------------------------------------------------------------
    public final void offer(Object e) {
        if (stack == null) stack = JsonPool.pollAnyArray();
        stack.add(e);
    }

    public final void poll() {
        if (stack != null) stack.poll();
    }

    public final boolean writeRefer(final Object value) {
        if (stack == null) return false;
        int index = stack.indexOf(value);
        if (index > -1) {
            int deep = stack.size() - index;
            if (deep < 0) throw new JsonException("the refer deep  value(" + deep + ") is illegal");
            write('{', '"', '@', '"', ':', '"');
            for (int i = 0; i < deep; i++) {
                write('@');
            }
            write('"', '}');
            return true;
        }
        return false;
    }

    //-----------------------------------------------------------------------
    public final int count() {
        return this.count;
    }

    public final void count(int count) {
        if (count >= 0) this.count = count;
    }

    public final void writeNull() {
        this.write('n', 'u', 'l', 'l');
    }

    public void release() {
        this.count = 0;
        if (stack != null) {
            JsonPool.offer(stack);
            this.stack = null;
        }
    }
    //-----------------------------------------------------------------------

    /**
     * 返回指定至少指定长度的缓冲区
     *
     * @param len
     * @return
     */
    public abstract char[] expand(final int len);

    public abstract void write(final char ch);

    public abstract void write(final char... chs);

    public abstract void write(final char[] chs, final int start, final int end);

    /**
     * 判断是否直接写进结果stream中，expand返返回的char[]是一个临时缓冲区的都应该返回true
     *
     * @return
     */
    public abstract boolean indirect();

    /**
     * <b>注意：</b> 该String值不能为null且不会进行转义， 只用于不含需要转义字符的字符串，例如enum、BigInteger转换的String
     *
     * @param quote
     * @param value
     */
    public abstract void write(final boolean quote, final String value);
}
